package com.xmall.sys.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmall.define.base.Result;
import com.xmall.define.dto.auth.AccountDto;
import com.xmall.define.dto.auth.AccountUpdateRequest;
import com.xmall.define.dto.login.PermissionDto;
import com.xmall.define.dto.login.UserDto;
import com.xmall.sys.define.dto.user.SysUserDto;
import com.xmall.sys.define.request.user.UserListPageQueryRequest;
import com.xmall.sys.define.request.user.UserRoleUpdateRequest;
import com.xmall.sys.define.request.user.UserUpdateRequest;
import com.xmall.sys.entity.Permission;
import com.xmall.sys.entity.User;
import com.xmall.sys.entity.UserRole;
import com.xmall.sys.mapper.UserMapper;
import com.xmall.sys.service.IPermissionService;
import com.xmall.sys.service.IUserRoleService;
import com.xmall.sys.service.IUserService;
import com.xmall.sys.service.remote.AuthAccountServiceFeign;
import com.xmall.sys.utils.ConvertUtils;
import com.xmall.utils.XmallUtils;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private IUserRoleService userRoleService;

    @Resource
    private IPermissionService permissionService;

    @Resource
    private AuthAccountServiceFeign authAccountServiceFeign;

    /**
     * 用户关联的角色ID列表
     */
    @Override
    public List<Long> userRoleIds(Long userId) {
        List<UserRole> userRoleList = userRoleService.list(new QueryWrapper<UserRole>().eq("user_id", userId));
        if(null == userRoleList || userRoleList.size() == 0){
            return new ArrayList<>();
        }
        return userRoleList.stream().map(entity -> entity.getRoleId()).collect(Collectors.toList());
    }

    /**
     * 详情
     */
    @Override
    public SysUserDto info(Long id) {
        User entity = getById(id);
        XmallUtils.notNull(entity);

        return ConvertUtils.UserModule.INSTANCE.toDto(entity);
    }

    /**
     * 用户权限信息
     */
    @Override
    public UserDto userPermission(Long id) {
        User user = getById(id);
        XmallUtils.notNull(user);

        UserDto result = new UserDto();
        BeanUtils.copyProperties(user, result);

        //根据用户ID查询权限信息
        List<Permission> permissionList = this.baseMapper.userPermissionList(id);
        if(null != permissionList){
            List<String> permissionArr = new ArrayList<>();
            //权限列表
            List<PermissionDto> permissionDtoList = permissionList.stream().map(entity -> {
                PermissionDto dto = new PermissionDto();
                BeanUtils.copyProperties(entity, dto);
                permissionArr.add(dto.getPermission());
                return dto;
            }).collect(Collectors.toList());
            result.setPermissionArr(permissionArr);
            //权限列表
            result.setPermissionList(permissionDtoList);
            //权限树
            result.setPermissionTreeList(permissionService.createTree(permissionList));
        }
        return result;
    }

    /**
     * 分页列表
     */
    @Override
    public Page<SysUserDto> listPage(UserListPageQueryRequest request) {
        Page<SysUserDto> result = new Page<>();

        //查询条件
        //TODO 此处代码需要重构
        QueryWrapper query = new QueryWrapper();
        query.like(StrUtil.isNotBlank(request.getNickname()), "nickname", request.getNickname());

        //分页
        Page<User> page = this.page(new Page(request.getPage(), request.getPageSize()), query);

        //转换属性
        BeanUtils.copyProperties(page, result);

        if(page.getTotal() > 0){
            //账号等其他属性查询
            List<Long> userIdList = page.getRecords().stream().map(user -> user.getId()).collect(Collectors.toList());
            Result<List<AccountDto>> accountListResult = authAccountServiceFeign.listByUserIds(userIdList);

            if(null != accountListResult && accountListResult.callSuccess()){
                Map<Long, AccountDto> accountDtoMap = accountListResult.getData().stream().collect(Collectors.toMap(AccountDto::getUserId, Function.identity(), (key1, key2) -> key2));

                //属性赋值
                result.setRecords(page.getRecords().stream().map(user -> {
                    SysUserDto dto = new SysUserDto();
                    Long userId = user.getId();
                    BeanUtils.copyProperties(user, dto);
                    BeanUtils.copyProperties(accountDtoMap.get(dto.getId()), dto);
                    dto.setId(userId);
                    return dto;
                }).collect(Collectors.toList()));
                return result;
            }else{
                return null;
            }
        }else{
            //属性赋值
            result.setRecords(page.getRecords().stream().map(user -> {
                SysUserDto dto = new SysUserDto();
                Long userId = user.getId();
                BeanUtils.copyProperties(user, dto);
                dto.setId(userId);
                return dto;
            }).collect(Collectors.toList()));
            return result;
        }
    }

    /**
     * 新增
     */
    @GlobalTransactional
    @Override
    public void saveEntity(UserUpdateRequest request) {
        //验证账号是否已存在
        Result<Boolean> accountExistsResult = authAccountServiceFeign.exist(request.getAccount());
        XmallUtils.checkRemoteResult(accountExistsResult);

        //保存用户信息
        User entity = ConvertUtils.UserModule.INSTANCE.toEntity(request);
        this.save(entity);

        //保存账号
        AccountUpdateRequest account = new AccountUpdateRequest();
        BeanUtils.copyProperties(request, account);
        account.setUserId(entity.getId());
        authAccountServiceFeign.save(account);
    }

    /**
     * 编辑
     */
    @Override
    public void updateEntity(UserUpdateRequest request) {
        User entity = this.getById(request.getId());
        XmallUtils.notNull(entity);

        User updateEntity = new User();
        updateEntity.setId(request.getId());
        updateEntity.setNickname(request.getNickname());
        this.updateById(updateEntity);
    }

    /**
     * 更新用户关联的角色列表
     */
    @Transactional
    @Override
    public void updateUserRole(UserRoleUpdateRequest request) {
        //删除之前所有关联关系
        userRoleService.remove(new QueryWrapper<UserRole>().eq("user_id", request.getUserId()));
        //新增关联关系列表
        List<UserRole> updateList = request.getRoleIds().stream().map(roleId -> {
            UserRole entity = new UserRole();
            entity.setUserId(request.getUserId());
            entity.setRoleId(roleId);
            return entity;
        }).collect(Collectors.toList());
        userRoleService.saveBatch(updateList);
    }
}
